package com.eastfair.venueservice.service.impl;

import cn.hutool.core.bean.BeanUtil;
//import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.annotation.annotation.cache.Cache;
import com.eastfair.annotation.annotation.cache.Magic;
import com.eastfair.boot.request.PageParams;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.context.StaticContextUtil;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.home.enumeration.ServiceProviderTypeEnum;
import com.eastfair.messagecenter.util.SendMsgUtil;
import com.eastfair.projectcore.enumeration.DataIsolationSystemSceneEnum;
import com.eastfair.venuebooking.dto.SpaceDTO;
import com.eastfair.venueservice.dao.SpaceAcceptanceMapper;
import com.eastfair.venueservice.dto.SpaceAcceptanceDTO;
import com.eastfair.venueservice.dto.SpaceAcceptanceQuery;
import com.eastfair.venueservice.entity.CreatCode;
import com.eastfair.venueservice.entity.ExhibitionManage;
import com.eastfair.venueservice.entity.ServiceProvider;
import com.eastfair.venueservice.entity.SpaceAcceptance;
import com.eastfair.venueservice.enumeration.SpaceAcceptanceDealResultEnum;
import com.eastfair.venueservice.enumeration.SpaceAcceptanceFinishStatusEnum;
import com.eastfair.venueservice.service.ExhibitionManageService;
import com.eastfair.venueservice.service.ServiceProviderService;
import com.eastfair.venueservice.service.SpaceAcceptanceService;
import com.eastfair.venueservice.vo.SpaceAcceptanceVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 业务实现类
 * 展厅验收记录
 * </p>
 *
 * @author linan
 * @date 2023-01-06
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class SpaceAcceptanceServiceImpl extends SuperServiceImpl<SpaceAcceptanceMapper, SpaceAcceptance> implements SpaceAcceptanceService {

    public static final String YS = "YS";
    public static final String ACCEPT_NO = "accept_no";

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Resource
    private ExhibitionManageService exhibitionManageService;

    @Resource
    private ServiceProviderService serviceProviderService;

    @Resource
    private SendMsgUtil sendMsgUtil;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<SpaceAcceptance> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(SpaceAcceptance model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        model.setTenantId(ContextUtil.getTenantId());
        return R.successDef();
    }

    /**
     * 通用查询
     *
     * @param modelDTO DTO
     * @param ids      主键id集合
     * @return list
     */
    @Override
    public List<SpaceAcceptance> list(SpaceAcceptanceDTO modelDTO, List<Long> ids) {
        return ((SpaceAcceptanceService) AopContext.currentProxy()).listOfCache(modelDTO, ids);
    }


    /**
     * 缓存查询
     *
     * @param modelDTO DTO
     * @param ids      主键id集合
     * @return list
     */
    @Override
    @Cache(key = "",
            magic = @Magic(
                    key = "{" +
                            "{'isEnabled', #args[0]?.isEnabled}," +
                            "{'exhibitionManageId', #args[0]?.exhibitionManageId}," +
                            "{'acceptNo', #args[0]?.acceptNo}," +
                            "{'companyType', #args[0]?.companyType}," +
                            "{'companyId', #args[0]?.companyId}," +
                            "{'companyName', #args[0]?.companyName}," +
                            "{'applicationName', #args[0]?.applicationName}," +
                            "{'phone', #args[0]?.phone}," +
                            "{'orgId', #args[0]?.orgId}," +
                            "{'orgName', #args[0]?.orgName}," +
                            "{'finishStatus', #args[0]?.finishStatus}," +
                            "{'dealResult', #args[0]?.dealResult}," +
                            "{'id', #args[1]}" +
                            "}"))
    public List<SpaceAcceptance> listOfCache(SpaceAcceptanceDTO modelDTO, List<Long> ids) {
        //查询
        QueryWrapper<SpaceAcceptance> queryWrapper = new QueryWrapper<>();
        if (modelDTO != null) {
            queryWrapper.lambda().eq(modelDTO.getExhibitionManageId() != null, SpaceAcceptance::getExhibitionManageId, modelDTO.getExhibitionManageId());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getAcceptNo()), SpaceAcceptance::getAcceptNo, modelDTO.getAcceptNo());
            queryWrapper.lambda().eq(Objects.nonNull(modelDTO.getCompanyType()), SpaceAcceptance::getCompanyType, modelDTO.getCompanyType());
            queryWrapper.lambda().eq(modelDTO.getCompanyId() != null, SpaceAcceptance::getCompanyId, modelDTO.getCompanyId());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getCompanyName()), SpaceAcceptance::getCompanyName, modelDTO.getCompanyName());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getApplicationName()), SpaceAcceptance::getApplicationName, modelDTO.getApplicationName());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getPhone()), SpaceAcceptance::getPhone, modelDTO.getPhone());
            queryWrapper.lambda().eq(modelDTO.getOrgId() != null, SpaceAcceptance::getOrgId, modelDTO.getOrgId());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getOrgName()), SpaceAcceptance::getOrgName, modelDTO.getOrgName());
            queryWrapper.lambda().eq(Objects.nonNull(modelDTO.getFinishStatus()), SpaceAcceptance::getFinishStatus, modelDTO.getFinishStatus());
            queryWrapper.lambda().eq(Objects.nonNull(modelDTO.getDealResult()), SpaceAcceptance::getDealResult, modelDTO.getDealResult());
        }
        if (ids != null && !ids.isEmpty()) {
            queryWrapper.lambda().in(SpaceAcceptance::getId, ids);
        }
        queryWrapper.lambda().eq(SpaceAcceptance::getIsDeleted, BusinessConstant.DELETE_NO);
        List<SpaceAcceptance> modelList = list(queryWrapper);
        return modelList;
    }

    @Override
    public Boolean saveSpaceAcceptance(SpaceAcceptanceDTO spaceAcceptanceDTO) {
        Long exhibitionManageId = spaceAcceptanceDTO.getExhibitionManageId();
        ExhibitionManage exhibitionManage = exhibitionManageService.getById(exhibitionManageId);
        String exhibitionName = Objects.nonNull(exhibitionManage) ? exhibitionManage.getExhibitionName() : Strings.EMPTY;
        Long companyId = spaceAcceptanceDTO.getCompanyId();
        ServiceProvider serviceProvider = serviceProviderService.getById(companyId);
        String serviceProviderName = Objects.nonNull(serviceProvider) ? serviceProvider.getCompanyName() : Strings.EMPTY;
        String companyType = Objects.nonNull(serviceProvider) ? ServiceProviderTypeEnum.get(serviceProvider.getServiceProviderType()).getDesc().substring(0,2) : Strings.EMPTY;
        for (SpaceDTO spaceDTO : spaceAcceptanceDTO.getSpaceList()) {
            SpaceAcceptance spaceAcceptance = BeanUtil.copyProperties(spaceAcceptanceDTO, SpaceAcceptance.class);
            String acceptNo = CreatCode.creatCode(baseMapper, ACCEPT_NO, 8, YS);
            spaceAcceptance.setAcceptNo(acceptNo);
            spaceAcceptance.setFinishStatus(SpaceAcceptanceFinishStatusEnum.NEED_DEAL);
            spaceAcceptance.setSpaceCode(spaceDTO.getSpaceCode());
            spaceAcceptance.setSpaceName(spaceDTO.getSpaceName());
            save(spaceAcceptance);
            // 异步处理，不影响正常保存
            threadPoolTaskExecutor.execute(()->{
                String content=String.format("%s，验收单号：%s，%s：%s已提交验收申请，请及时处理！",exhibitionName,acceptNo,companyType,serviceProviderName);
                log.info(content);
                sendMsgUtil.sendInnerMsg(content, StaticContextUtil.getProjectSystemScene());
            });
        }
        return true;
    }

    @Override
    public IPage<SpaceAcceptanceVO> querySpaceAcceptance(PageParams<SpaceAcceptanceQuery> params) {
        Page<SpaceAcceptance> buildPage = params.buildPage();
        SpaceAcceptanceQuery model = params.getModel();
        QueryWrapper<SpaceAcceptance> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(SpaceAcceptance::getIsDeleted,BusinessConstant.NO)
                .eq(Objects.nonNull(model.getCompanyType()), SpaceAcceptance::getCompanyType,model.getCompanyType())
                .ne(ContextUtil.getSystemScene().equals(DataIsolationSystemSceneEnum.P_COMPOSITE_VENUE.getCode()), SpaceAcceptance::getIsEnabled ,BusinessConstant.NO)
                .eq(Objects.nonNull(model.getOrgId()), SpaceAcceptance::getOrgId,model.getOrgId())
                .eq(Objects.nonNull(model.getCompanyId()), SpaceAcceptance::getCompanyId,model.getCompanyId())
                .eq(Objects.nonNull(model.getFinishStatus()), SpaceAcceptance::getFinishStatus,model.getFinishStatus())
                .eq(Objects.nonNull(model.getExhibitionManageId()), SpaceAcceptance::getExhibitionManageId,model.getExhibitionManageId())
                .like(Objects.nonNull(model.getAcceptNo()), SpaceAcceptance::getAcceptNo,model.getAcceptNo())
                .like(Objects.nonNull(model.getSpaceName()), SpaceAcceptance::getSpaceName,model.getSpaceName())
                .and(StringUtils.isNotBlank(model.getKeywords()),
                        e -> e.like(SpaceAcceptance::getAcceptNo, model.getKeywords())
                                .or().like(SpaceAcceptance::getCompanyName, model.getKeywords())
                                .or().like(SpaceAcceptance::getApplicationName, model.getKeywords())
                                .or().like(SpaceAcceptance::getPhone, model.getKeywords()));
        Page<SpaceAcceptance> page = page(buildPage, wrapper);
        Page<SpaceAcceptanceVO> spaceAcceptanceVOPage = ConvertUtil.convertPage(page, SpaceAcceptanceVO.class);
        return spaceAcceptanceVOPage;
    }

    @Override
    public SpaceAcceptance getByAcceptNo(String acceptNo) {
        return getOne(new QueryWrapper<SpaceAcceptance>().lambda()
                .eq(SpaceAcceptance::getIsDeleted,BusinessConstant.NO).eq(SpaceAcceptance::getAcceptNo,acceptNo));
    }

    @Override
    public void updateFinishStatus(String acceptNo, SpaceAcceptanceFinishStatusEnum finished, SpaceAcceptanceDealResultEnum spaceAcceptanceDealResultEnum) {
        SpaceAcceptance spaceAcceptance = getByAcceptNo(acceptNo);
        SpaceAcceptance updateEntity = new SpaceAcceptance();
        updateEntity.setId(spaceAcceptance.getId());
        updateEntity.setFinishStatus(finished);
        updateEntity.setDealResult(spaceAcceptanceDealResultEnum);
        updateById(updateEntity);
    }


    /**
     * do转vo
     *
     * @param model model
     * @return modelVo
     */
    @Override
    public SpaceAcceptanceVO doToVo(SpaceAcceptance model) {
        SpaceAcceptanceVO modelVo = new SpaceAcceptanceVO();
        BeanUtils.copyProperties(model, modelVo);
        modelVo.setId(model.getId());
        return modelVo;
    }

    /**
     * do转vo
     *
     * @param modelList modelList
     * @return list
     */
    @Override
    public List<SpaceAcceptanceVO> doToVos(List<SpaceAcceptance> modelList) {
        if (modelList == null || modelList.isEmpty()) {
            return null;
        }
        List<SpaceAcceptanceVO> result = new ArrayList<>();
        for (SpaceAcceptance model : modelList) {
            result.add(doToVo(model));
        }
        return result;
    }
}
